package com.zlsy.thread.deadlock;


/**
 * @author zhouliang
 * @date 2020/05/12
 * <p>
 * 转账的时候遇到死锁，一旦打开注释，便会发生死锁。
 **/
public class TransferMoney implements Runnable {

    int flag = 1;
    static Account a = new Account(500);
    static Account b = new Account(500);

    public TransferMoney(int flag) {
        this.flag = flag;
    }

    public static void main(String[] args) throws InterruptedException {
        TransferMoney r1 = new TransferMoney(1);
        TransferMoney r2 = new TransferMoney(0);

        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r2);

        t1.start();
        t2.start();

        t1.join();
        t2.join();

        System.out.println("a的余额" + a.balance);
        System.out.println("b的余额" + b.balance);
    }

    @Override
    public void run() {
        if (flag == 1) {
            transferMoney(a, b, 200);
        }
        if (flag == 0) {
            transferMoney(b, a, 200);
        }
    }

    public static void transferMoney(Account from, Account to, int amount) {
        synchronized (from) {
            //假如加了这段睡眠时间，就模拟业务中获取锁可能阻塞，r1拿到了自己账户的锁想去拿r2账户的锁，
            //但是r2也拿到了自己账户的锁想去拿R1，持有自己的锁，想去拿对方的锁，于是死锁
     /*       try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*/
            synchronized (to) {
                if (from.balance - amount < 0) {
                    System.out.println("余额不足，转账失败！");
                }
                from.balance = from.balance - amount;
                to.balance = to.balance + amount;
                System.out.println("成功转账" + amount + "元！");
            }
        }
    }

    /**
     * 账户
     */
    static class Account {

        private int balance;

        public Account(int balance) {
            this.balance = balance;
        }
    }
}
